package edu.xidian.sei

import java.text.DecimalFormat
import scala.collection.mutable.HashMap
import scala.collection.mutable.HashSet
import scala.collection.mutable.ArrayBuffer
import java.io.File
import scala.io.Source
import java.io.PrintWriter

object Purity2 {
  def main(args: Array[String]): Unit = {
    val fileNameStart = "label"
    val filereader = Source.fromFile(fileNameStart + ".txt")
    val linenum = Source.fromFile(fileNameStart + ".txt").getLines.size
    var i = 0
    var arrayLine = new ArrayBuffer[String]
    val set = findFiles("./", "location")
    set.foreach(println)
    for (line <- filereader.getLines()) {
      i = i + 1
      arrayLine += line
      //      if(i % 13515 == 0 || i == linenum){
      if (set.contains(i.toString()) || i == linenum) {
        val writer = new PrintWriter(new File(fileNameStart + i))
        for (l <- arrayLine) {
          writer.println(l)
        }
        writer.close()
        arrayLine.clear()
      }
    }

    val resultMap = new HashMap[String, Tuple2[Double, Int]]
    var score = 0.0
    set.foreach { id =>
      val s = computePurity(fileNameStart, id)
      resultMap.put(id, s)
      score = score + s._1
    }
    println("平均精度：" + score / set.size)
    //    computePurity(fileNameStart, "22260")
    resultMap.foreach(pair => println(pair._1 + ": " + pair._2))

  }
  def findFiles(path: String, name: String): HashSet[String] = {
    val fileNmesList = new HashSet[String]()
    val file = new File(path);
    val files = file.listFiles()
    val fileNames = file.list()
    files.foreach { f =>
      if (f.isFile() && f.getName().startsWith(name)) {
        fileNmesList.add(f.getName.split("_")(1))
      }
    }
    fileNmesList
  }

  def computePurity(fileNameStart: String, id: String): Tuple2[Double, Int] = {
    val locationMap = new HashMap[String, String]
    //val IndexMap = new HashMap[String, String]
    val classMap = new HashMap[String, String]
    val filereader1 = Source.fromFile("location_" + id)
    // println(Source.fromFile("location_485136").getLines.size)
    for (line <- filereader1.getLines) {
      val strs = line.split("=>")
      locationMap.put(strs(0), strs(1))
    }
    //    val filereader2 = Source.fromFile("index2new_" + id)
    //    for (line <- filereader2.getLines) {
    //      val strs = line.split("=>")
    //      IndexMap.put(strs(0), strs(1))
    //    }
    val filereader3 = Source.fromFile("output_" + id + ".txt")
    for (line <- filereader3.getLines) {
      val strs = line.split("=>")
      classMap.put(strs(0), strs(1))
    }

    val finalBuffer = new ArrayBuffer[(String, String)]
    locationMap.foreach(pair => {

      if (classMap.contains(pair._2)) {
        finalBuffer += Tuple2(pair._1, classMap.get(pair._2).get)
      } else {
        //println("newIndex:" + index)
        //finalBuffer += Tuple2(pair._1, "-1")
      }

    })
    //    println(finalBuffer.size + " " + finalBuffer.toMap.size)
    //
    //    println(locationMap.size + " " + IndexMap.size + " " + classMap.size)
    val finalMap = finalBuffer.toMap
    val resultMap = new HashMap[String, Int]
    val filereaderFinal = Source.fromFile(fileNameStart + id)
    val format = new DecimalFormat("0.0000");
    var pointNum = 0.0
    for (line <- filereaderFinal.getLines) {
      pointNum = pointNum + 1
      val className = line.split(",").takeRight(1)(0)
      //val className = 1
      val point = line.split(",").map(x => format.format(x.toDouble)).take(2).mkString(",")
      //println(point)
      if (finalMap.contains(point)) {
        val clusterName = finalMap.get(point).get
        val result = clusterName + "=>" + className
        if (resultMap.contains(result)) {
          val value = resultMap.get(result).get + 1
          resultMap.put(result, value)
        } else {
          resultMap.put(result, 1)
        }
      }
    }

    println("====================================================")
    resultMap.foreach(pair => println(pair._1 + " " + pair._2))
    println("point_Num:" + pointNum)
    println("resultMap_Size:" + resultMap.values.sum)
    var sum = 0
    var max = 0
    val tempClassSet = new HashSet[String]
    val tempClusterSet = new HashSet[String]
    //    val resuklt = resultMap.toArray.sortWith((pair1, pair2) => pair1._2 > pair2._2).map (x => {
    //      (x._1.split("=>")(1), (x._2, x._1.split("=>")(0)))
    //    }).groupBy(_._1).foreach(x => {
    //      var max = 0
    //      var maxID = ""
    //      x._2.foreach(x => {
    //        if (x._2._1.toInt > max) {
    //          max = x._2._1.toInt
    //          maxID = x._2._2
    //        }
    //        //       println(x._1 + " " + x._2)&& !tempSet.contains(x._2._2)
    //      })
    //      println(x._1 + ":" + max + " " + maxID)
    //      //tempSet.add(maxID)
    //      sum += max
    //    })

    val resuklt = resultMap.toArray.sortWith((pair1, pair2) => pair1._2 > pair2._2).map(x => {
      (x._1.split("=>")(1), (x._2, x._1.split("=>")(0)))
    }).foreach { pair =>
      if (!tempClassSet.contains(pair._1) && !tempClusterSet.contains(pair._2._2)) {
        println(pair._1 + ":" + pair._2._1 + " " + pair._2._2)
        tempClassSet.add(pair._1)
        tempClusterSet.add(pair._2._2)
        sum += pair._2._1
      }
    }

    //println("sum:" + sum)
    println(sum / pointNum)
    val format1 = new DecimalFormat("0.000");
    (format1.format(sum / pointNum).toDouble, classMap.values.toSet.size)
  }

}